import importlib
import time
import urllib
from hashlib import sha1
import hmac
import base64
import uuid
import sys
from .constants import EDITOR_EXT_MAP, X_FILE_ID, X_USER_TOKEN
from flask import current_app, request, g


def get_latest_version(fileid):
    """获取最新的版本"""
    pass


def get_wps_url(fileid, userid):
    """获取wps_url"""
    file_model_file = importlib.import_module(
        current_app.config['MODOLE_FILE_PATH'])  # 导入models模块
    File = getattr(file_model_file, current_app.config['FILE_CLASS_NAME'])  # 反射并实例化
    user_model_file = importlib.import_module(
        current_app.config['MODOLE_USER_PATH'])  # 导入models模块
    getattr(user_model_file, current_app.config['USER_CLASS_NAME'])  # 反射并实例化
    f = File.objects(id=fileid).first()
    if not f:
        return {'code': 10005}
    # t 文件类型
    t = EDITOR_EXT_MAP[getattr(
        f, current_app.config['FILE_ATTR_NAME_MAP']['name']).split('.')[-1]]
    # 默认参数,需根据需求修改
    values = {}
    values.setdefault("_w_appid", current_app.config['APPID'])
    values.setdefault("_w_tokentype", "1")  # 必须携带,回调才会有token
    values.setdefault("_w_userid", userid)
    signature = sign(values, current_app.config['APPKEY'])
    weboffice_url = "{}/office/{}/{}?{}&_w_signature={}".format(
        current_app.config['DOMAIN'], t, fileid, urllib.parse.urlencode(values), signature)
    return weboffice_url


def sign(values, secret_key):
    """签名"""
    contents = string_to_sign(values, secret_key)
    signature = urllib.parse.quote(hash_hmac(contents, secret_key, sha1))
    return signature


def string_to_sign(values, secret_key):
    """得到待加密的字符串"""
    keys = []
    for k in values.keys():
        keys.append(k)
    keys.sort()
    s = ''
    for key in keys:
        s += '{}={}'.format(key, values[key])
    s += "_w_secretkey={}".format(secret_key)
    return s


def hash_hmac(code, key, sha1):
    """加密"""
    hmac_code = hmac.new(key.encode(), code.encode(), sha1).digest()
    return base64.b64encode(hmac_code).decode()


def generate_token():
    """生成token"""
    u = str(uuid.uuid4())
    token = no_hyphen_string(u)
    return token


def no_hyphen_string(u):
    """获取没有-字符的字符串"""
    return ''.join(u.split('-'))


def check_token():
    """检查token"""
    access_token = request.headers.get(X_USER_TOKEN)


def check_open_signature():
    """检查签名"""
    sign_query = {}
    for k, v in g.params.items():
        if '_w_' in k:
            sign_query[k] = v
    signature = urllib.parse.unquote(g.params.get("_w_signature"))
    if not signature:
        return {
            "code": 40005,
            "message": "InvalidArgument",
            "details": "invaid signature",
            "hint": "invaid signature"

        }
    del sign_query["_w_signature"]
    authorization = sign(sign_query, current_app.config.get('APPKEY'))
    if authorization != signature:
        print("error : authorization:{} and signature:{} \n".format(
            authorization, signature))
        return {
            "code": 40005,
            "message": "InvalidArgument",
            "details": "signature mismatch",
            "hint": "signature mismatch"
        }


def check_fileid():
    """检查文件id"""
    fileid = request.headers.get(X_FILE_ID)
    if fileid == "":
        return {
            "code": 40005,
            "message": "InvalidArgument",
            "details": "header missing param x-weboffice-file-id",
            "hint": "header missing param x-weboffice-file-id"

        }
    if not exist_fileid(fileid):
        print("error : fileid is not exist")
        return {
            "code": 40005,
            "message": "InvalidArgument",
            "details": "fileid is not exist",
            "hint": "fileid is not exist"
        }
    request.headers[X_FILE_ID] = fileid


def check_user_agent():
    """检查用户代理"""
    agent = request.headers.get("User-Agent")
    print("CheckUserAgent agent:{}".format(agent))
    if agent == "":
        print("error : agent is not exist")
        return {
            "code": 40005,
            "message": "InvalidArgument",
            "details": "header missing param User-Agent",
            "hint": "header missing param User-Agent"
        }


def check_appid():
    """检查appid"""
    appid = g.params.get("_w_appid")
    if appid == "":
        return {
            "code": 40005,
            "message": "InvalidRequest",
            "details": "missing param _w_appid",
            "hint": "missing param _w_appid"
        }


def exist_fileid(fileid):
    """检查文件id是否存在"""
    model = importlib.import_module(
        current_app.config['MODOLE_FILE_PATH'])  # 导入models模块
    File = getattr(model, current_app.config['FILE_CLASS_NAME'])  # 反射并实例化
    file_instance = File.objects(id=fileid).first()
    if file_instance:
        return True
    else:
        return False


def get_context_fileid():
    """从请求头中获取fileid"""
    return request.headers.get(X_FILE_ID)


def datetime_to_timestamp(dtime):
    ans_time = time.mktime(dtime.timetuple())
    return int(ans_time)
